分散システムデザインパターン ―コンテナを使ったスケーラブルなサービスの設計

本書から何を学びたいか

コンテナ化の理由

目次

1章 はじめに
1.1 システム開発の歴史概観
1.2 ソフトウェア開発におけるパターンの歴史概観
1.2.1 アルゴリズムによるプログラミングの形式化
1.2.2 オブジェクト指向プログラミングのパターン
1.2.3 オープンソースソフトウェアの隆盛
1.3 パターン、慣習、コンポーネントの価値
1.3.1 巨人の肩の上に立つ
1.3.2 1 つのやり方を議論するための共通言語
1.3.3 簡単に再利用できる共有コンポーネント
1.4 まとめ
第Ⅰ部 シングルノードパターン
Ⅰ.1 シングルノードパターンを使う理由
Ⅰ.2 まとめ
2章 サイドカー
2.1 サイドカーの例:レガシーサービスのHTTPS 対応
2.2 サイドカーによる動的な設定
2.3 モジュール化されたアプリケーションコンテナ
2.3.1 ハンズオン:topz コンテナのデプロイ
2.4 サイドカーを使ったシンプルなPaaS の構築
2.5 モジュール化と再利用性を考えたサイドカーの設計
2.5.1 パラメータ化されたコンテナ
2.5.2 各コンテナのAPI 仕様の設計
2.5.3 コンテナのドキュメント化
2.6 まとめ
3章 アンバサダ
3.1 サービスのシャーディングへのアンバサダの利用
3.1.1 ハンズオン:シャーディングされたRedis の実装
3.2 サービスブローカとしての利用
3.3 新システムの実験的運用やリクエスト分割への利用
3.3.1 ハンズオン:10% のアクセスのみ実験用システムに送る
4章 アダプタ
4.1 監視
4.1.1 ハンズオン:監視へのPrometheus の利用
4.2 ロギング
4.2.1 ハンズオン:Fluentd による各種ロギングフォーマットの正規化
4.3 ヘルスモニタの追加
4.3.1 ハンズオン:MySQL のリッチなステータス監視の追加
第Ⅱ部 マルチノードパターン
Ⅱ.1 マイクロサービス入門
5章 レプリカがロードバランスされたサービス
5.1 ステートレスなサービス
5.1.1 ロードバランスのためのReadiness Probe
5.1.2 ハンズオン:Kubernetes 上でのレプリカを使ったサービスの構築
5.2 セッションを保存するサービス
5.3 アプリケーションレイヤでレプリカを扱うサービス
5.4 キャッシュレイヤの導入
5.4.1 キャッシュのデプロイ
5.4.2 ハンズオン:キャッシュレイヤのデプロイ
5.5 キャッシュレイヤの拡張
5.5.1 帯域制限とDoS 攻撃に対する防御
5.5.2 SSL 終端
5.5.3 ハンズオン:nginx とSSL 終端のデプロイ
5.6 まとめ
6章 シャーディングされたサービス
6.1 シャーディングされたキャッシュ
6.1.1 シャーディングされたキャッシュの必要性
6.1.2 アーキテクチャ内でのキャッシュの役割
6.1.3 シャーディングされたキャッシュのレプリカ
6.1.4 ハンズオン:アンバサダのデプロイとシャーディングされたmemcached
6.2 シャーディング関数を試してみる
6.2.1 キーの選択
6.2.2 コンシステントハッシュ関数
6.2.3 ハンズオン:コンシステントなHTTP シャーディングプロキシの構築
6.3 シャーディングされたレプリカを使ったシステム
6.4 ホットシャーディングシステム
7章 スキャッタ・ギャザー
7.1 ルートによる分散とスキャッタ・ギャザー
7.1.1 ハンズオン:分散ドキュメント検索
7.2 リーフをシャーディングしたスキャッタ・ギャザー
7.2.1 ハンズオン:シャーディングされたドキュメント検索
7.2.2 適切なリーフ数の決め方
7.3 信頼性とスケーラビリティのためのスキャッタ・ギャザーのスケール
8章 ファンクションとイベント駆動処理
8.1 FaaS を使うべき時の判断
8.1.1 FaaS の利点
8.1.2 FaaS の課題
8.1.3 バックグラウンド処理の必要性
8.1.4 データをメモリに置いておく必要性
8.1.5 リクエストベースの処理を保持しておくコスト
8.2 FaaS のパターン
8.2.1 デコレータパターン:リクエストまたはレスポンスの変換
8.2.2 ハンズオン:リクエスト処理前のデフォルト値設定
8.2.3 イベントの扱い
8.2.4 ハンズオン:2 要素認証の実装
8.2.5 イベントベースのパイプライン
8.2.6 ハンズオン:新規ユーザ登録のパイプライン実装
9章 オーナーシップの選出
9.1 マスタ選出の必要性の判断
9.2 マスタ選出の基本
9.2.1 ハンズオン:etcd のデプロイ
9.2.2 ロックの実装
9.2.3 ハンズオン:etcd でのロックの実装
9.2.4 オーナーシップの実装
9.2.5 ハンズオン:etcd での期間指定付きロックの実装
9.3 並列データ操作の扱い
第Ⅲ部 バッチ処理パターン
10章 ワークキューシステム
10.1 汎用ワークキューシステム
10.1.1 ソースコンテナインタフェイス
10.1.2 ワーカコンテナインタフェイス
10.1.3 共有ワークキュー基盤
10.2 ハンズオン:動画サムネイル作成の実装
10.3 ワーカの動的スケール
10.4 マルチワーカパターン
11章 イベント駆動バッチ処理
11.1 イベント駆動処理のパターン
11.1.1 コピア
11.1.2 フィルタ
11.1.3 スプリッタ
11.1.4 シャーダ
11.1.5 マージャ
11.2 ハンズオン:イベント駆動な新規ユーザ登録フローの構築
11.3 パブリッシャ・サブスクライバ(pub/sub)基盤
11.4 ハンズオン:Kafka のデプロイ
12章 協調的バッチ処理
12.1 結合(またはバリア同期)
12.2 Reduce
12.2.1 ハンズオン:カウント
12.2.2 合計
12.2.3 ヒストグラム
12.3 ハンズオン:画像のタグ付けと処理パイプライン
13章 まとめ:新しい始まり?

第Ⅰ部 シングルノードパターン

コンテナ化のゴール
リソースの分離(一定のリソースに境界を設ける)
このアプリケーションは2CPUコアと8GBのメモリが必要
チームのオーナーシップの境界
このチームはこのコンテナイメージを管理している

サイドカー

アプリケーションコンテナ
サイドカーコンテナ
アプリケーションコンテナを拡張・改善する
そのままだと拡張するのが難しいコンテナに、機能を追加するために使われる
サイドカーコンテナは、Kubernetesにおけるpod APIオブジェクトのような、アトミックなコンテナグループを通じて、同じマシン上に割り当てられる
アプリケーションコンテナとサイドカーコンテナは、ファイルシステムの一部、ホスト名、ネットワーク、それ以外のネームスペースなどの多くを共有する
レガシーアプリケーションに対して、比較的容易に機能追加を行える
コンテナの監視機能を追加できる
パラメータ化することでコンテナを実行するたびに呼び出す「関数」にすることができる
API 

3章 アンバサダ

3.2 サービスブローカとしての利用

アプリケーションを複数環境間(例えばパブリッククラウド、物理データセンタ、プライベートクラウド)でポータブルに扱う際の大きな問題の1つがサービスディスカバリと設定の扱い
ポータブルなアプリケーションを作るには、アプリケーションは環境を認識し、接続すべき適切なサービス(例えば、MySQLサービス)を見つけなければならない
このようなプロセスのことをサービスディスカバリと言い、ディスカバリと紐付けをを行うシステムを一般的にサービスプローカと言う

4章 アダプタ

デザインパターンはそれを利用する開発者だけのものとは限らない
デザインパターンを通じて、コミュニティメンバ間、さらにはより広い開発者のエコシステムの中でコラボレーションしたり、やり方を共有することになり、コミュニティの進歩を促すことになる

マルチノードパターン

Ⅱ.1 マイクロサービス入門

マイクロサービスとは、別々のプロセスとして動作し、定義済みのAPIを通じて通信する多くのコンポーネントからなるシステムのこと
マイクロサービスは、サービスの全機能を1つの密結合なアプリケーションにまとめたモノシリックなシステムと対比した言葉

信頼性とすばやさに関連するもの
アプリケーションを小さな部品に分け、それぞれが1つのサービスを提供することに集中する
スコープを狭め、チームサイズを小さくすると、チームの焦点を合わせ、方向性を一致させることに関するオーバーヘッドも小さくできる
マイクロサービス間にしっかりとしたAPIを導入することでチームを分離し、サービス間に信頼性の高い決め事を作ることにつながる
APIを提供する側は、何を変えないようにしなければならないかが理解できる
APIを利用する側は、細かいことを気にしなくても安定したサービスに依存できる
チーム間が同期して動く必要性を下げてくれる
分離によって、各チームは独立してコードやリリーススケジュールを管理できる
チームの能力を反復して改善したり、コードを改善したりできる
マイクロサービスの分離によって、スケールが容易となる
マイクロサービスの欠点
システムが疎結合のため、問題が起きた時のデバッグが難しい
サービス間通信に複数の方式を使い、違ったパターン(同期、非同期、message passingなど)が存在し、サービス間の協調や制御にもさまざまな方法がある

5章 レプリカがロードバランスされたサービス

IPベースのセッション保存はクラスタ内(内部IPアドレス)では動作するが、外部IPアドレスを使用した場合、NAT(network address translation)のため正常に動作しないことが多い
外部セッションの保存には、アプリケーションレベルでセッションを保存(Cookieを利用するなど)した方がよい

セッションの保存は、コンシステントハッシュ関数(consistent hassing function)を利用することが多い
コンシステントハッシュ関数は、キー数を変更後のシャード数で割った数だけをマッピングし直すよう保証された、特殊なハッシュ関数

8章 ファンクションとイベント工藤処理

8.1.1 FaaSの利点

コードと実環境に稼働するサービスの距離が劇的に短くなる
デプロイされたコードは自動的に管理されスケールされる
ファンクションで作ったシステムは自然にモジュール化され、分離される

8.2.2 FaaSの課題

強制的な分離により、サービス開発のすばやさ、高速さをあげることができるが、サービスの運用は難しくなる

8.2.3 イベントの扱い

リクエストとイベントの違いは、セッションの観点
リクエストとは大きなやりとりあるいはセッションの流れの一部
通常、ユーザからの各リクエストは完全なWebアプリケーションやAPIにおける大きな流れの一部
イベントとは1回限りのインスタンスであり、非同期である契合がある
イベント
新しいサービスにユーザがサインイン(ようこそメール送信)
ファイルを共有フォルダにアップロード(フォルダへのアクセス権を持つユーザに通知を送る)
マシンのリブート(オペレータに通知を送る、適切な対応を取るよう自動化する)


Links

関心の分離separation of concernsmeganii.iconレガシーアプリケーションサービスディスカバリサービスプローカデザインパターンマイクロサービスAPIFaaSセッションリクエスト駆動イベント駆動Brendan Burnsオライリージャパン

Tags

技術書